package xyy.d3erpapi.service.impl;

import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import xyy.d3erpapi.pojo.d3po.*;
import xyy.d3erpapi.pojo.poppo.PopErpSkuStockV2Dto;
import xyy.d3erpapi.pojo.poppo.SellerOrderDeliverDetailDto;
import xyy.d3erpapi.pojo.poppo.SellerOrderDeliverInfoDto;
import xyy.d3erpapi.service.D3Service;
import xyy.d3erpapi.service.PopApiService;
import xyy.d3erpapi.service.PopService;
import xyy.d3erpapi.utils.HttpRequestUtil;
import xyy.d3erpapi.utils.JsonUtils;
import xyy.d3erpapi.utils.MD5Util;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.stream.Collectors;


@Slf4j
@Service
public class D3ServiceImpl implements D3Service {
    @Autowired
   private PopApiService popApiService;

    @Value("${d3.appsecret}")
    private  String APP_SECRET ;
    @Value("${d3.appkey}")
    private String d3appKey;
    @Value("${d3.baseurl}")
    private  String baseUrl;
    //回调接口 验证签名 方法
    @Override
    public boolean validateSignature(Map<String, String> publicParams, String jsonBusinessParams, String sign) {


       
        // 第一步：对公共参数按照参数名称的ASCII码表的顺序排序
        StringBuilder sortedPublicParams = new StringBuilder();

        // 使用 TreeMap 对键进行排序
        TreeMap<String, String> sortedParams = new TreeMap<>(publicParams);
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            sortedPublicParams.append(entry.getKey());
            sortedPublicParams.append(entry.getValue());
        }

        // 第四步：拼接步骤1和步骤2的结果
        String combinedString = sortedPublicParams.toString() + jsonBusinessParams;
        // 第五步：在拼接的字符串前后添加 appSecret
        String finalString = APP_SECRET + combinedString + APP_SECRET;
//bc4c902f8cfe560aeb1f65c2e22e095cappKey221325imestamp1730109302543methodds.omni.mall.third.order.deliveryreqIdjZYxAhEWumtagsync{"content":[{"packages":[{"expressCode":"2410281001001","lines":[{"num":1,"outerId":"","refOlId":"227798506","refProductId":"GEQ0015","refSkuId":"GEQ0015"},{"num":2,"outerId":"","refOlId":"227798507","refProductId":"KEB0007","refSkuId":"KEB0007"}],"logisticsCode":"0006","logisticsName":"中通快递","shippingType":"OFFLINE"}],"posCode":"ybm1001","refOid":"YBM20241028170220202832"}]}bc4c902f8cfe560aeb1f65c2e22e095c        // 第六步：使用 MD5 算法对最终字符串进行摘要并返回十六进制表示
        String expectedSign = MD5Util.md5Hex(finalString);

        System.out.println("加密后的字符串："+expectedSign);
        return expectedSign.equalsIgnoreCase(sign);





    }

    //调用点3接口，加密方法
    @Override
    public String validateSignatureToUpper(Map<String, String> publicParams, String jsonBusinessParams) {



        // 第一步：对公共参数按照参数名称的ASCII码表的顺序排序
        StringBuilder sortedPublicParams = new StringBuilder();

        // 使用 TreeMap 对键进行排序
        TreeMap<String, String> sortedParams = new TreeMap<>(publicParams);
        for (Map.Entry<String, String> entry : sortedParams.entrySet()) {
            sortedPublicParams.append(entry.getKey());
            sortedPublicParams.append(entry.getValue());
        }

        // 第四步：拼接步骤1和步骤2的结果
        String combinedString = sortedPublicParams.toString() + jsonBusinessParams.toString();
        // 第五步：在拼接的字符串前后添加 appSecret
        String finalString = APP_SECRET + combinedString + APP_SECRET;
//bc4c902f8cfe560aeb1f65c2e22e095cappKey221325methodds.omni.mall.sale.order.gettimestamp1729596950651YBM20241013151505150893bc4c902f8cfe560aeb1f65c2e22e095c
        // 第六步：使用 MD5 算法对最终字符串进行摘要并返回十六进制表示
        return MD5Util.md5HexToUpper(finalString);

    }

    // 处理库存更新的异步方法
    @Async("AsyncExecutor") // 指定自定义线程池
    public CompletableFuture<List<PopErpSkuStockV2Dto>> processInventoryUpdate(InventoryUpdateRequest request) {
        log.info("处理库存同步数据: {}", request);

        List<PopErpSkuStockV2Dto> popErpSkuStockV2Dtos = new ArrayList<>();

        // 验证内容是否为空
        if (request.getContent() == null || request.getContent().isEmpty()) {
            log.warn("库存更新请求内容为空");
            return CompletableFuture.completedFuture(popErpSkuStockV2Dtos);
        }

        try {
            // 数据是数组，给 PopErpSkuStockV2Dto 赋值
            for (InventoryUpdateRequest.InventoryItem inventoryItem : request.getContent()) {
                PopErpSkuStockV2Dto popErpSkuStockV2Dto = new PopErpSkuStockV2Dto();
                popErpSkuStockV2Dto.setErpCode(inventoryItem.getOuterId());
                popErpSkuStockV2Dto.setAvailableQyt(inventoryItem.getQuantity().intValue());
                popErpSkuStockV2Dtos.add(popErpSkuStockV2Dto);
            }
            //do 删了！！！
           // Thread.sleep(2000); // 模拟长时间处理
        }  catch (Exception e) {
            log.error("处理库存同步数据时发生异常", e);
            return CompletableFuture.completedFuture(popErpSkuStockV2Dtos); // 返回处理到目前为止的结果
        }

        log.info("库存同步处理完成，返回 SKU 数据: {}", popErpSkuStockV2Dtos);
        return CompletableFuture.completedFuture(popErpSkuStockV2Dtos); // 返回填充好的 SKU DTO 列表
    }

    @Async("AsyncExecutor") // 指定自定义线程池
    public CompletableFuture<List<SellerOrderDeliverInfoDto>> convertToOrderDeliverInfo(LogisticsRequestDto logisticsRequestDto) {
        log.info("处理物流数据: {}", logisticsRequestDto);

        List<SellerOrderDeliverInfoDto> sellerOrderDeliverInfoDtos = new ArrayList<>();

        // 验证内容是否为空
        if (logisticsRequestDto == null || logisticsRequestDto.getContent() == null || logisticsRequestDto.getContent().isEmpty()) {
            log.warn("物流数据为空");
            return CompletableFuture.completedFuture(sellerOrderDeliverInfoDtos);
        }

        try {

            // 数据是数组，给 SellerOrderDeliverInfoDtos 赋值
            sellerOrderDeliverInfoDtos = logisticsRequestDto.getContent().stream()
                    .map(logisticsContent -> createSellerOrderDeliverInfoDto(logisticsContent))
                    .collect(Collectors.toList());

            // DO 模拟长时间处理
            //Thread.sleep(2000); // 如果需要，您可以在这里保留这个模拟延迟
        } catch (Exception e) {
            log.error("处理物流同步数据时发生异常", e);
            return CompletableFuture.completedFuture(sellerOrderDeliverInfoDtos); // 返回处理到目前为止的结果
        }

        log.info("物流信息同步处理完成，返回 SKU 数据: {}", sellerOrderDeliverInfoDtos);
        return CompletableFuture.completedFuture(sellerOrderDeliverInfoDtos); // 返回填充好的 SKU DTO 列表
    }

    private SellerOrderDeliverInfoDto createSellerOrderDeliverInfoDto(LogisticsRequestDto.Content logisticsContent) {
        SellerOrderDeliverInfoDto sellerOrderDeliverinfoDto = new SellerOrderDeliverInfoDto();
        sellerOrderDeliverinfoDto.setOrderNo(logisticsContent.getRefOid());

        // 设置物流公司和运单号
        if (logisticsContent.getPackages() != null && !logisticsContent.getPackages().isEmpty()) {

            for (LogisticsRequestDto.Package aPackage : logisticsContent.getPackages()) {
                if (aPackage != null) {
                    String expressName = aPackage.getLogisticsName();
                    String expressCode = aPackage.getExpressCode();

                    if (expressName != null) {
                        if (expressName.contains("中通")) {
                            sellerOrderDeliverinfoDto.setLogiCompany("中通快递");
                            sellerOrderDeliverinfoDto.setLogiNo("8");
                        } else if (expressName.contains("圆通")) {
                            sellerOrderDeliverinfoDto.setLogiCompany("圆通快递");
                            sellerOrderDeliverinfoDto.setLogiNo("5");
                        } else {
                            sellerOrderDeliverinfoDto.setLogiCompany("其他快递");
                            sellerOrderDeliverinfoDto.setLogiNo("20");
                        }
                    } else {
                        log.warn("快递名称为 null，包裹信息: {}", aPackage);
                    }

                    if (expressCode != null) {
                        sellerOrderDeliverinfoDto.setDeliveryId(expressCode);
                    } else {
                        log.warn("快递单号为 null，包裹信息: {}", aPackage);
                    }
                } else {
                    log.warn("包裹信息为 null");
                }
            }
        } else {
            log.warn("物流内容中的包裹列表为空或为 null，reference OID: {}", logisticsContent.getRefOid());
        }

        return sellerOrderDeliverinfoDto;
    }


    @Override
    public List<SellerOrderDeliverDetailDto> QueryD3OrderInfo(List<String> orderNos) {

        List<SellerOrderDeliverDetailDto> allSaleOrderInfo = new ArrayList<>(); // 创建一个列表保存所有的订单信息

        //调用点3订单查询接口，返回点三订单类集合
        for (String orderNo : orderNos) {
            QueryOrderRequestDTO queryOrderRequestDTO = new QueryOrderRequestDTO();
            queryOrderRequestDTO.setCode(orderNo);

            //上报出库数据
            // 拼装需要加密的公共参数
            Map<String, String> publicParams = new HashMap<>();
            publicParams.put("appKey", d3appKey);
            publicParams.put("method", "ds.omni.mall.sale.order.get");
            publicParams.put("timestamp", String.valueOf(System.currentTimeMillis())); // 生成当前时间戳

            // 使用通用工具类将 orderDTO 转换为 JSON 字符串
            String jsonBusinessParams = JsonUtils.toJson(queryOrderRequestDTO);//orderDTO

            //生成sign
            String sign = validateSignatureToUpper(publicParams,jsonBusinessParams);
            //
            publicParams.put("sign",sign);

            //调方法 发请求
            List<SellerOrderDeliverDetailDto> saleOrderInfo = getSaleOrderInfo(publicParams, jsonBusinessParams);

// 将当前订单信息添加到总集合中
            allSaleOrderInfo.addAll(saleOrderInfo); // 合并当前订单信息到总列表
        }



        return allSaleOrderInfo;

    }
    //获取点三订单数据  并转换成出库对象
    private List<SellerOrderDeliverDetailDto> getSaleOrderInfo(Map<String, String> publicParams, String code) {

        // 构建 URL
        String requestUrl = HttpRequestUtil.buildUrl(baseUrl, publicParams);
        String requestBodyString = code;

        // 打印完成的请求参数
        log.info("请求参数: URL: {}, Method: POST, 请求体: {}", requestUrl, requestBodyString);

        List<SellerOrderDeliverDetailDto> sellerOrderDeliverDetailDtoList = new ArrayList<>();

        // 发送 POST 请求并处理响应
        try {
            String responseBody = HttpRequestUtil.post(requestUrl, requestBodyString);

            // 解析响应体 fastjson
            QueryOrderResponseDTO queryOrderResponseDTO = JSON.parseObject(responseBody, QueryOrderResponseDTO.class);

            if ("200".equals(queryOrderResponseDTO.getResponse().getCode())) {
                List<QueryOrderResponseDTO.OrderDTO> content = queryOrderResponseDTO.getResponse().getData().getContent();

                if (content.isEmpty()) {
                    log.warn("没有找到D3订单数据。");
                } else {
                    for (QueryOrderResponseDTO.OrderDTO order : content)  {
                        for (QueryOrderResponseDTO.LineItem lineItem : order.getLineList()) {
                            SellerOrderDeliverDetailDto sellerOrderDeliverDetailDto = new SellerOrderDeliverDetailDto();
                            sellerOrderDeliverDetailDto.setOrderNo(order.getCode());
                            sellerOrderDeliverDetailDto.setProductName(lineItem.getTitle());
                            sellerOrderDeliverDetailDto.setBatchPrice(BigDecimal.valueOf(lineItem.getPrice()));
                            sellerOrderDeliverDetailDto.setBatchNumDecimal(BigDecimal.valueOf(lineItem.getNum()));
                            sellerOrderDeliverDetailDto.setBatchCode("");//无返回值
                            sellerOrderDeliverDetailDto.setErpCode(lineItem.getOuterId());
                           // sellerOrderDeliverDetailDto.setBatchValidDate("");
                            sellerOrderDeliverDetailDto.setOrderDetailId(Long.parseLong(lineItem.getRefOlId()));

                            sellerOrderDeliverDetailDtoList.add(sellerOrderDeliverDetailDto);
                        }
                    }
                }
            } else {
                log.error("请求失败，响应代码: {}", queryOrderResponseDTO.getResponse().getCode());
            }

        } catch (Exception e) {
            log.error("请求或解析响应失败: {}", e.getMessage());
            return sellerOrderDeliverDetailDtoList; // 返回空列表
        }

        return sellerOrderDeliverDetailDtoList; // 返回得到的集合
    }

}



